package com.xhl.doeverything.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.xhl.doeverything.dao.UserDao;
import com.xhl.doeverything.dto.UserRequest;
import com.xhl.doeverything.entity.ApiResult;
import com.xhl.doeverything.entity.UserDO;
import com.xhl.doeverything.po.User;
import com.xhl.doeverything.rabbitmq.constant.SysEventExchangeName;
import com.xhl.doeverything.rabbitmq.constant.SysEventRoutingKey;
import com.xhl.doeverything.rabbitmq.service.MessageSender;
import com.xhl.doeverything.redis.RedisDistributedLock;
import com.xhl.doeverything.redis.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author xionghuilong
 * @description: test
 * @date 2021/11/12 15:36
 */
@RestController
@Order(1)
@Api(tags = "测试controller")
@Slf4j
public class TestController {
    @Resource
    private UserDao userDao;
    @Resource
    private MessageSender messageSender;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private RedisDistributedLock redisDistributedLock;
    @Resource
    private RedisUtil redisUtil;

    @PostMapping("sayHello")
    public String sayHello(@RequestBody UserRequest userRequest, HttpServletRequest request) throws JsonProcessingException {
        return "hello~~";
    }

    @PostMapping("testMQ")
    @ApiOperation("rabbitMQ整合测试")
    public ApiResult<String> testMQ(@RequestBody User user){

        // 发送消息
        messageSender.send(SysEventExchangeName.USER_EXCHANGE,
                SysEventRoutingKey.USER_ROUTING,
                JSONUtil.toJsonStr(user));
        return ApiResult.success("message send success!");
    }

    @PostMapping("testRedis")
    @ApiOperation("redis整合测试-入库")
    public ApiResult<String> testRedis(@RequestParam(value="paramStr") String paramStr){
        this.redisUtil.set("name",paramStr);
        return ApiResult.success("ok~");
    }

    @PostMapping("testRedisGet")
    @ApiOperation("redis整合测试-查询")
    public ApiResult<Object> testRedisGet(@RequestParam(value="key") String key){
        Object values = null;
        log.info("has key 【" + key + "】->{}",this.redisUtil.hasKey(key));
        if(this.redisUtil.hasKey(key)){
            values = this.redisUtil.get(key);
        }
        return ApiResult.success(values);
    }

    @GetMapping("testRedisDistributedLock")
    @ApiOperation("redis分布式锁整合测试")
    public ApiResult<String> testRedisDistributedLock(){
        boolean lock = false;
        String key = "lockkey";
        try {
            lock = redisDistributedLock.lock(key, 10000L, 10, 1000L);
            if(!lock){
                log.error(Thread.currentThread() +  "----------未获取到锁-----------");
                return ApiResult.fail("repeat request");
            }
            log.info("处理业务中。。");
            Thread.sleep(2000l);
            log.info("业务处理结束。。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(lock){
                redisDistributedLock.releaseLock(key);
            }
        }
        return ApiResult.success("success");
    }

    @PostMapping("cacheTest")
    @ApiOperation("Cacheable缓存注解测试")
    @Cacheable(value = "user_cache",key="#name")
    public List<UserDO> cacheTest(@RequestParam(value="name") String name){
        List<UserDO> userList = this.userDao.selectList(new LambdaQueryWrapper<UserDO>().like(UserDO::getName,name));
        return userList;
    }

    @PostMapping("cacheTest2")
    @ApiOperation("使用redisTemplate获取Cacheable缓存数据")
    public Object cacheTest2(@RequestParam(value="name") String name){
        return this.redisUtil.get("user_cache::" + name);
    }
}
